/*  Copyright © 2009 Blake Hegerle -*- C++ -*- */

/*  This file is part of metal.
 
    Metal is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see
    <http://www.gnu.org/licenses/>.

*/

#pragma once

#include "../forward.h"

namespace metal {
  namespace meta {
    struct arithmatic_tag { };
    struct integral_tag { };
    struct boolean_tag { };
    struct comparison_tag { };

    template<typename I>
    struct ident_expr { };

    template<
      typename Tag, 
      typename Left, 
      typename Right
      >
    struct binary_expr { };

    template<typename Tag, typename Expr>
    struct unary_expr { };

    template<typename P>
    struct constant_expr { };

    template<typename I, typename... Args>
    struct call_expr { };

    template<typename Expr, typename... Bindings>
    struct eval_expr { };

    template<typename Expr, typename... Bindings>
    struct map_expr { };

    template<typename... Elems>
    struct array_expr { };

    template<typename IfExpr, typename ThenExpr, typename ElseExpr>
    struct cond_expr { };

    template<
      typename Expr,
      typename I, 
      typename Range, 
      typename Filter
      >
    struct filter_expr { };

    template<typename ArrayExpr, typename IndexExpr>
    struct subscript_expr { };

    template<typename Expr, typename M>
    struct dot_expr { };

    template<typename T, typename... Args>
    struct cons_expr { };

    template<typename Type, typename Expr>
    struct cast_expr { };
    
    template<typename Type, typename Body, typename... Args>
    struct lambda_expr { };

    // helper func

    template<typename T>
    struct meta_expr {
      typedef void type;
    };

    template<typename T>
    struct meta_expr<expression<T> > {
      typedef T type;
    };
  }
}
